#include <iostream>
using namespace std;
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>

int main()
{
    int pipeFd[2];
    /* 创建管道 */
    pipe(pipeFd);

    /* 查看管道缓冲区大小 */
    cout << "pipe:" << fpathconf(pipeFd[0], _PC_PIPE_BUF) << endl;
    cout << "pipe:" << fpathconf(pipeFd[1], _PC_PIPE_BUF) << endl;

    /* 创建进程 */
    pid_t pid = fork();
    if (pid < 0)
    {
        perror("fork error:");
        exit(-1);
    }
    else if (pid == 0)
    {
        /* 关闭写端 */
        close(pipeFd[1]);
        sleep(3);

        /* 设置pipeFd[0]文件描述符为非阻塞 */

        /* 1.得到文件描述符的原本属性 */
        int flags = fcntl(pipeFd[0], F_GETFL);
        /* 2.在原本的属性上面增加新的属性(非阻塞) */
        flags |= O_NONBLOCK;
        /* 3.设置附加上的属性到文件描述符 */
        fcntl(pipeFd[0], F_SETFL, flags);

        cout << "子进程,从管道中读取数据..." << endl;

        /* 子进程 */
        int recvMoney = 0;
        // int readBytes = read(pipeFd[0], &recvMoney, sizeof(recvMoney));
        // cout << "readBytes:" << readBytes << ", child recvMoney:" << recvMoney << endl;

        char buffer[3] = {0};
        int readBytes = 0;

        while (1)
        {
            int readBytes = read(pipeFd[0], buffer, sizeof(buffer) - 1);

            if (readBytes < 0)
            {
                if (errno == EAGAIN)
                {
                    cout << "non block..." << endl;
                }
                else
                {
                    perror("read error:");
                }
                /* 退出进程 */
                _exit(-1);
            }
            if (readBytes < sizeof(buffer) - 1)
            {
                cout << "buffer:" << buffer << endl;
                break;
            }

            cout << "buffer:" << buffer << endl;
            memset(buffer, 0, sizeof(buffer));
        }
    }
    else
    {
        /* 关闭读端 */
        close(pipeFd[0]);

        /*父进程*/
        int money = 5000000;

        cout << "父进程,延时5s向管道写数据" << endl;
        /* 延时10s, --- 让出CPU */
        sleep(1);

        /* 向管道写端写数据 */
        // write(pipeFd[1], static_cast<const void *>(&money), sizeof(money));
        const char *data = "helloworld";
        write(pipeFd[1], static_cast<const void *>(data), strlen(data));

        /* 回收子进程资源 */
        wait(NULL); // 不回收 --> 孤儿进程
    }

    return 0;
}